"""
Generate sample data for attribution analysis examples.
"""
import pandas as pd
import numpy as np
from datetime import datetime, timedelta


def generate_ecommerce_data(
    start_date: str = "2024-01-01",
    days: int = 60,
    seed: int = 42
) -> pd.DataFrame:
    """
    Generate sample e-commerce data with intentional patterns and anomalies.

    Args:
        start_date: Start date for data generation
        days: Number of days to generate
        seed: Random seed for reproducibility

    Returns:
        DataFrame with e-commerce metrics and dimensions
    """
    np.random.seed(seed)

    # Generate dates
    start = datetime.strptime(start_date, "%Y-%m-%d")
    dates = [start + timedelta(days=i) for i in range(days)]

    # Dimensions
    regions = ['North', 'South', 'East', 'West']
    products = ['Product_A', 'Product_B', 'Product_C', 'Product_D']
    channels = ['Web', 'Mobile', 'Store']

    data = []

    for date in dates:
        day_of_week = date.weekday()

        for region in regions:
            for product in products:
                for channel in channels:
                    # Base metrics
                    base_visits = np.random.poisson(100)

                    # Add day-of-week pattern
                    if day_of_week >= 5:  # Weekend
                        base_visits = int(base_visits * 1.2)

                    # Add regional patterns
                    if region == 'North':
                        base_visits = int(base_visits * 1.3)
                    elif region == 'South':
                        base_visits = int(base_visits * 0.8)

                    # Add product popularity
                    if product == 'Product_A':
                        conversion_rate = 0.05
                    elif product == 'Product_B':
                        conversion_rate = 0.03
                    else:
                        conversion_rate = 0.02

                    # Add channel effect
                    if channel == 'Web':
                        conversion_rate *= 1.2
                    elif channel == 'Store':
                        conversion_rate *= 1.5

                    # Introduce anomaly: Product_B performance drop in Week 6
                    if product == 'Product_B' and 35 <= (date - start).days <= 42:
                        conversion_rate *= 0.5

                    # Introduce anomaly: North region spike in Week 7
                    if region == 'North' and 42 <= (date - start).days <= 49:
                        base_visits = int(base_visits * 1.8)

                    # Calculate metrics
                    visits = base_visits
                    conversions = np.random.binomial(visits, conversion_rate)
                    avg_order_value = np.random.normal(50, 10)
                    revenue = conversions * avg_order_value

                    data.append({
                        'date': date,
                        'region': region,
                        'product': product,
                        'channel': channel,
                        'visits': visits,
                        'conversions': conversions,
                        'revenue': revenue,
                        'avg_order_value': avg_order_value
                    })

    df = pd.DataFrame(data)
    return df


def generate_saas_data(
    start_date: str = "2024-01-01",
    days: int = 60,
    seed: int = 42
) -> pd.DataFrame:
    """
    Generate sample SaaS metrics data.

    Args:
        start_date: Start date for data generation
        days: Number of days to generate
        seed: Random seed for reproducibility

    Returns:
        DataFrame with SaaS metrics
    """
    np.random.seed(seed)

    start = datetime.strptime(start_date, "%Y-%m-%d")
    dates = [start + timedelta(days=i) for i in range(days)]

    plans = ['Free', 'Basic', 'Pro', 'Enterprise']
    industries = ['Tech', 'Finance', 'Healthcare', 'Retail']

    data = []

    for date in dates:
        for plan in plans:
            for industry in industries:
                # Base users
                if plan == 'Free':
                    users = np.random.poisson(1000)
                    price = 0
                elif plan == 'Basic':
                    users = np.random.poisson(300)
                    price = 29
                elif plan == 'Pro':
                    users = np.random.poisson(100)
                    price = 99
                else:  # Enterprise
                    users = np.random.poisson(20)
                    price = 499

                # Industry effect
                if industry == 'Tech':
                    users = int(users * 1.3)
                elif industry == 'Finance':
                    # Finance converts better to paid plans
                    if plan != 'Free':
                        users = int(users * 1.5)

                # Introduce churn anomaly for Pro plan in Healthcare in Week 5
                if plan == 'Pro' and industry == 'Healthcare' and 28 <= (date - start).days <= 35:
                    users = int(users * 0.6)

                mrr = users * price
                active_users = int(users * np.random.uniform(0.7, 0.9))

                data.append({
                    'date': date,
                    'plan': plan,
                    'industry': industry,
                    'users': users,
                    'active_users': active_users,
                    'price': price,
                    'mrr': mrr
                })

    return pd.DataFrame(data)


def generate_marketing_data(
    start_date: str = "2024-01-01",
    days: int = 60,
    seed: int = 42
) -> pd.DataFrame:
    """
    Generate sample marketing campaign data.

    Args:
        start_date: Start date for data generation
        days: Number of days to generate
        seed: Random seed for reproducibility

    Returns:
        DataFrame with marketing metrics
    """
    np.random.seed(seed)

    start = datetime.strptime(start_date, "%Y-%m-%d")
    dates = [start + timedelta(days=i) for i in range(days)]

    campaigns = ['Brand_Awareness', 'Lead_Gen', 'Retargeting', 'Seasonal']
    ad_platforms = ['Google', 'Facebook', 'LinkedIn', 'Twitter']

    data = []

    for date in dates:
        for campaign in campaigns:
            for platform in ad_platforms:
                # Base metrics
                impressions = np.random.poisson(10000)
                ctr = np.random.uniform(0.01, 0.05)

                # Campaign type effects
                if campaign == 'Retargeting':
                    ctr *= 2.0
                elif campaign == 'Brand_Awareness':
                    impressions *= 2.0
                    ctr *= 0.5

                # Platform effects
                if platform == 'Facebook':
                    impressions *= 1.5
                    ctr *= 0.8
                elif platform == 'LinkedIn':
                    impressions *= 0.5
                    ctr *= 1.5

                # Introduce anomaly: Facebook performance drop in Week 7
                if platform == 'Facebook' and 42 <= (date - start).days <= 49:
                    ctr *= 0.4

                clicks = int(impressions * ctr)
                cpc = np.random.uniform(0.5, 3.0)
                cost = clicks * cpc

                data.append({
                    'date': date,
                    'campaign': campaign,
                    'platform': platform,
                    'impressions': impressions,
                    'clicks': clicks,
                    'cost': cost,
                    'ctr': ctr,
                    'cpc': cpc
                })

    return pd.DataFrame(data)


if __name__ == "__main__":
    # Generate and save sample datasets
    ecommerce = generate_ecommerce_data()
    ecommerce.to_csv("ecommerce_data.csv", index=False)
    print(f"Generated e-commerce data: {len(ecommerce)} rows")
    print(ecommerce.head())

    saas = generate_saas_data()
    saas.to_csv("saas_data.csv", index=False)
    print(f"\nGenerated SaaS data: {len(saas)} rows")
    print(saas.head())

    marketing = generate_marketing_data()
    marketing.to_csv("marketing_data.csv", index=False)
    print(f"\nGenerated marketing data: {len(marketing)} rows")
    print(marketing.head())
